#ifndef ROCKYASSISTERX_H
#define ROCKYASSISTERX_H

#include <QtWidgets/QMainWindow>
#include <QtserialPort/QserialPort>
#include <QtserialPort/QserialPortInfo>
#include <QTimer>
#include <QElapsedTimer>
#include "ui_rockyassisterx.h"
#include "qswitchbutton.h"
#include "neure.h"

#define UPDATE_COM_PORT_TIME_MS					( 500 )

class rockyAssisterX : public QMainWindow
{
	Q_OBJECT

public:
	static const int neure_assign_time_ms;

public:
	rockyAssisterX(QWidget *parent = 0);
	~rockyAssisterX();

signals:
	void comPortUpdateSw(bool);

private slots:
	void on_comPortBox_currentIndexChanged(const QString &text);
	void on_comPortBox_highlighted(const QString &Text);
	void on_comPortBox_activated(const QString &Text);
	
	void serial_read_data(void);
	void ui_enable(bool);

	void on_pushButton_Disc_clicked(void);

	// car
	// void on_forwardHorizontalSlider_valueChanged(int);
	void on_backwardHorizontalSlider_valueChanged(int);
	void on_leftDcMotorHorizontalSlider_valueChanged(int);
	void on_rightDcMotorHorizontalSlider_valueChanged(int);
	void on_leftTurnPushButton_clicked(void);
	void on_rightTurnPushButton_clicked(void);
	void on_stopPushButton_clicked(void);
	void on_DcSampleCurrentCheckBox_toggled(bool);
	void on_setRpushButton_clicked(void);
	void on_setGpushButton_clicked(void);
	void on_setBpushButton_clicked(void);

	// Color
	void on_caliPushButton_clicked(void);
	void on_getRgbPushButton_clicked(void);
	void on_getColorPushButton_clicked(void);
	void on_getVisibleEnvPushButton_clicked(void);
	void on_getVisibleWhiteReflectPushButton_clicked(void);
	void on_getVisibleReflectPushButton_clicked(void);
	void on_getIrReflectPushButton_clicked(void);
	void on_ifObstaclePushButton_clicked(void);
	
	// Polling
	void on_rgbPollCheckBox_toggled(bool);
	void on_rgbChangeRadioButton_toggled(bool);
	void on_rgbPollLineEdit_textChanged(QString);

	void on_colorPollCheckBox_toggled(bool);
	void on_colorChangeRadioButton_toggled(bool);
	void on_colorPolllineEdit_textChanged(QString);

	void on_VisibleEnvPollCheckBox_toggled(bool);
	void on_visibleEnvChangeRadioButton_toggled(bool);
	void on_visibleEnvPolllineEdit_textChanged(QString);

	void on_VisibleGrayPollCheckBox_toggled(bool);
	void on_visibleGrayChangeRadioButton_toggled(bool);
	void on_visibleGrayPolllineEdit_textChanged(QString);

	void on_visibleReflectPollCheckBox_toggled(bool);
	void on_visibleReflectChangeRadioButton_toggled(bool);
	void on_visibleReflectPolllineEdit_textChanged(QString);

	void on_irReflectPollCheckBox_toggled(bool);
	void on_irReflectChangeRadioButton_toggled(bool);
	void on_irReflectPolllineEdit_textChanged(QString);

	void on_ObstaclePollCheckBox_toggled(bool);
	void on_obstacleChangeRadioButton_toggled(bool);
	void on_ObstaclePollLineEdit_textChanged(QString);

	// trace line
	void on_pushButton_start_clicked(void);
	void on_pushButton_stop_clicked(void);
	void pid_proc(void);
	void pid_recv_feedback(quint8);

	// Console
	void on_ClearPushButton_clicked(void);
	void on_SendPushButton_clicked(void);
	void on_TimingSendcheckBox_toggled(bool);
	void on_timinglineEdit_textChanged(QString);

	/*Comport*/
	void comPortToggle(bool);
	void comPortOpen(void);
	void comPortClose(void);
	
	/**/
	void updateComPortList(void);
	void on_comPortBox_clicked(void);

	void logOut(QString);
	void devOnlineUpdate(bool, quint8);
	void firmwareUpdate(QString);
	void rgbUpdate(quint16, quint16, quint16);
	void colorUpdate(quint16, quint16, quint16, QString);
	void envUpdate(quint8);
	void grayUpdate(quint8);
	void visibleReflectUpdate(quint8);
	void irReflectUpdate(quint8);
	void obstacleUpdate(quint8);
	void dcCurrentUpdate(quint16, quint16);

	/*
	App setting
	*/
	void readSettings(void);
	void writeSettings(void);

	/*
	Event process
	*/
	void closeEvent(QCloseEvent *event);

private:
	Ui::rockyAssisterXClass ui;
	bool m_serialOpen;
	QSerialPort *m_serial;
	SwitchControl *m_comSwBtn;
	neure *m_ser_neure;
	bool m_r, m_g, m_b;
	QTimer *m_send_timer;

	// pid trace line
	QTimer m_pid_timer;
	QElapsedTimer m_elapsedTimer;
	qint64 avg_rsp_time_cnt, avg_rsp_time_sum, m_t0, m_t1;
	bool m_rsp_time_clear;

	float m_Kp, m_Ki, m_Kd;
	float m_Kd_last_out;
	float m_Kd_lowpass;
	int m_err, m_last_err, m_last_last_err;
	int m_trace_gray, m_trace_speed, m_cur_incream, m_max_incream;

	// statistics
	int m_err_cnt, m_err_sum;

};

#endif // ROCKYASSISTERX_H
